import importlib

import yaml
import numpy as np
from ..satellite_formation import relative_sate_form

from .basic_variable import basic_variable
from ..target_list import target_list

class relative_delta_v(basic_variable):
    '''
    基于Darwin运动学模型的卫星编队建模
    参考文献《Micropropulsion Technology Assessment for DARWIN》
    '''
    
    def __init__(self, yaml_config: yaml.nodes.Node):
        self.__formation_status = yaml_config.get("InitialFormationStatus", {})     # 队列初始状态
        self.__mir_wave_length = yaml_config.get("MIRWaveLength", 10.) * 1.e-6     # 观测波段 / 微米

    @staticmethod
    def param_list():
        return ['ra', 'dec', 't_tot', 'hz_inner', 'hz_outer', 't_exposure', 'N_cover']

    def initialize(self, tg_list: target_list):
        # 卫星编队初始化
        #formation_type = 'relative_sate_form'
        #sate_form_clz = getattr(importlib.import_module(f".satellite_formation.{formation_type}", package="miyinff"), formation_type)
        sate_form_obj = relative_sate_form(self.__formation_status)

        '''
        单位统一
        将hz_inner， hz_outer单位由毫角秒换为弧度
        将t_exposure单位由小时换为天
        '''
        for i in range(tg_list.len):
            tg_list[i][4] = tg_list[i][4] / 1e3 / 3600. / 180. * np.pi
            tg_list[i][5] = tg_list[i][5] / 1e3 / 3600. / 180. * np.pi
            tg_list[i][6] = tg_list[i][6] / 24.

        '''
        计算常数参数，节省迭代时间
        half_diagonal_inner: 编队观测最短基线 / 米[8]
        half_diagonal_outer: 编队观测最长基线 / 米[9]
        obs_time: 编队旋转+观测总时长 / day[10]
        obs_delta_v: 编队旋转+观测总速度增量 / m/s[11]
        end_phase : 观测模式末相位 / rad[12]
        '''
        # 计算观测基线
        #half_diagonal = [0.59 * self.__mir_wave_length / ((tgline[4] + tgline[5]) / 2.) / 2. for tgline in tg_list]
        half_diagonal_inner = [0.59 * self.__mir_wave_length / (tgline[5] * np.sin(sate_form_obj.form_theta) * 2.) for tgline in tg_list]
        tg_list.add_row('half_diagonal_inner', half_diagonal_inner)
        
        # 计算编队旋转用时及速度增量
        obs_info = []
        for tg in tg_list:
            rotation_time, rotation_delta_v, end_phase, half_diagonal_outer = sate_form_obj.observe_model(hz_inner=tg[4], hz_outer=tg[5], t_obs=tg[6], mir_wave_length=self.__mir_wave_length)
            obs_info.append([half_diagonal_outer, rotation_time, rotation_delta_v, end_phase])

        tg_list.add_rows(['half_diagonal_outer', 'rotation_time', 'rotation_delta_v', 'end_phase'], obs_info)

        return tg_list, sate_form_obj

    def filter(self, target_list: np.ndarray, sate_form: relative_sate_form):
        # 筛选当前黄道经度满足可视角度要求的目标
        index = np.abs(target_list[:,1] - sate_form.orbit_lon) < sate_form.visual_angle
        target_list = target_list[index]
        
        # 计算完成下一任务需要的总时间（编队转向+t_tot）
        target_finish_time = self.evaluate(target_list, sate_form)

        # 筛选任务完成时仍在可视角度内的目标
        sate_finish_obrit_lon = sate_form.orbit_lon + target_finish_time * sate_form.orbit_rotate_angular_velocity
        index = (target_list[:,1] - sate_finish_obrit_lon) < sate_form.visual_angle
        return target_list[index]

    def evaluate(self, target_list: np.ndarray, sate_form: relative_sate_form) -> np.ndarray:
    
        trans_cost = np.zeros(len(target_list), dtype = np.float64)
        for i, tg in enumerate(target_list):
            #trans_cost[i,0], trans_cost[i,1], trans_cost[i,2] = sate_form.transform_cost(coord_star=[tg[1], tg[2]], half_diagonal=tg[8])
            _, trans_cost[i], _ = sate_form.transform_cost(coord_star=[tg[1], tg[2]], half_diagonal_inner=tg[8], half_diagonal_outer=tg[9])

        target_finish_time = trans_cost + target_list[:,10]

        return target_finish_time
